#pragma once

#include <list>

#include "../base/eec/mutex.hpp"
#include "../base/eec/semaphore.hpp"

namespace base {

template<typename T>
class HMsgQueue
{
public:
	explicit HMsgQueue() { }
	~HMsgQueue() { };

public:
	bool get(T& _t, int _timeout = 0xFFFFFFFF);
	void set(const T& _t);

private:
	std::list<T> container_;

	base::eec::mutex lock_;
    base::eec::semaphore semaphore_;
};

template<typename T>
inline bool HMsgQueue<T>::get(T& _t, int _timeout)
{
    if (!semaphore_.wait(_timeout)) {
        return false;
    }

	base::eec::lock_guard<base::eec::mutex> l_lock_guard(lock_);
    if (container_.empty()) {
        return false;
    }
    _t = container_.front();
	container_.pop_front();
	return true;
}

template<typename T>
inline void HMsgQueue<T>::set(const T & _t)
{
	base::eec::lock_guard<base::eec::mutex> l_lock_guard(lock_);
	container_.push_back(_t);
    semaphore_.notify();
}

} // namespace base

